#include "CustomTablemodel.h"
#include<QFileIconProvider>
CustomTablemodel::CustomTablemodel(QObject *parent)
    : QAbstractTableModel(parent)
{
    // 初始化表头
    m_horizontalHeaders << "序号" << "文件名" << "文档类型" << "文档格式"
                        << "大小" << "创建时间" << "更新时间" << "操作";
}
CustomTablemodel::~CustomTablemodel()
{
}

int CustomTablemodel::rowCount(const QModelIndex &parent) const
{
    //由于视图为表格用不到parent
    Q_UNUSED(parent)
    return m_tableData.size();
}

int CustomTablemodel::columnCount(const QModelIndex &parent) const
{
    //由于视图为表格用不到parent
    Q_UNUSED(parent)
    return m_horizontalHeaders.size();
}

QVariant CustomTablemodel::data(const QModelIndex &index, int role) const
{
    //用户操作单元格位置不合法返回空
    if (!index.isValid() || index.row() >= m_tableData.size())
        return QVariant();
    //拿到index处的单元格
    const TableItem &item = m_tableData.at(index.row());
    int column = index.column();
    //看一下数据是用来干嘛的
    switch (role) {
    case Qt::DisplayRole:
    case Qt::EditRole:
        switch (column) {
        case 0: // 序号
            return index.row() + 1;
        case 1: // 文件名
            return item.fileName;
        case 2: // 文档类型
            return docTypeToString(item.docType);
        case 3: // 文档格式
            return item.docFormat;
        case 4: // 大小
            return item.size;
        case 5: // 创建时间
            return item.createTime.toString("yyyy-M-d");
        case 6: // 更新时间
            return item.updateTime.toString("yyyy-M-d");
        case 7: // 操作
            return "上传 删除 查看";
        default:
            return QVariant();
        }

    case Qt::DecorationRole:
        if (column == 1 && !item.icon.isNull()) {
            return item.icon;
        }
        break;

    case Qt::BackgroundRole:
        // 根据状态设置背景色
        return getStatusColor(item.status);

    case Qt::TextAlignmentRole:
        return Qt::AlignCenter;

    case Qt::ToolTipRole:
        if (column == 2) {
            return "点击选择文档类型";
        }
        return QString("文件: %1\n类型: %2\n大小: %3")
            .arg(item.fileName)
            .arg(docTypeToString(item.docType))
            .arg(item.size);
    }

    return QVariant();
}

QVariant CustomTablemodel::headerData(int section, Qt::Orientation orientation, int role) const
{
    //我们只考虑显示角色的请求
    if (role != Qt::DisplayRole)
        return QVariant();
    //如果表格是横向的表头
    if (orientation == Qt::Horizontal) {
        if (section < m_horizontalHeaders.size())
            return m_horizontalHeaders.at(section);
    }

    return QVariant();
}

bool CustomTablemodel::setData(const QModelIndex &index, const QVariant &value, int role)
{
    //只有编辑的时候我们处理
    if (!index.isValid() || role != Qt::EditRole)
        return false;

    int row = index.row();
    int column = index.column();
    //进行合法性判断
    if (row < 0 || row >= m_tableData.size())
        return false;
    //拿到一行数据
    TableItem &item = m_tableData[row];
    //下面设置列
    switch (column) {
    case 1: // 文件名
        item.fileName = value.toString();
        break;
    case 2: // 文档类型
        item.docType = stringToDocType(value.toString());
        break;
    case 3: // 文档格式
        item.docFormat = value.toString();
        break;
    case 4: // 大小
        item.size = value.toString();
        break;
    default:
        return false;
    }

    emit dataChanged(index, index);
    return true;
}

Qt::ItemFlags CustomTablemodel::flags(const QModelIndex &index) const
{
    //设置单元格是否可以被编辑
    Qt::ItemFlags flags = QAbstractTableModel::flags(index);
    if (index.isValid()) {
        int column = index.column();
        // 文件名、文档类型、文档格式、大小可编辑
        if (column >= 1 && column <= 4) {
            flags |= Qt::ItemIsEditable;
        }
    }
    return flags;
}

void CustomTablemodel::setHorizontalHeader(const QStringList &headers)
{
    beginResetModel();
    m_horizontalHeaders = headers;
    endResetModel();
}

void CustomTablemodel::addItem(const TableItem &item)
{
    //通知视图我要开始更新模型数据了
    beginInsertRows(QModelIndex(), m_tableData.size(), m_tableData.size());
    m_tableData.append(item);
    //更新完毕
    endInsertRows();
}

void CustomTablemodel::removeItem(int row)
{
    //行号合法性判断
    if (row < 0 || row >= m_tableData.size())
        return;
    //开始删除行
    beginRemoveRows(QModelIndex(), row, row);
    m_tableData.removeAt(row);
    //删除完成
    endRemoveRows();
}

void CustomTablemodel::clearAll()
{
    //清空模型
    beginResetModel();
    m_tableData.clear();
    endResetModel();
}

void CustomTablemodel::setItemStatus(int row, int status)
{
    if (row < 0 || row >= m_tableData.size())
        return;
    //更新row行的状态 用来更新我们一行的颜色
    m_tableData[row].status = status;
    // 创建模型索引 指定跟新的范围为整个视图
    QModelIndex topLeft = createIndex(row, 0);
    QModelIndex bottomRight = createIndex(row, columnCount() - 1);
    emit dataChanged(topLeft, bottomRight);
}

void CustomTablemodel::setItemIcon(int row, const QIcon &icon)
{
    if (row < 0 || row >= m_tableData.size())
        return;
    //设置图标
    m_tableData[row].icon = icon;
    //也是创建索引 提醒视图更新数据第row行第2类1列单元格
    QModelIndex changedIndex = createIndex(row, 1);
    emit dataChanged(changedIndex, changedIndex);
}

TableItem CustomTablemodel::getItem(int row) const
{
    //获取一整行数据
    if (row >= 0 && row < m_tableData.size())
        return m_tableData.at(row);

    return TableItem();
}

QString CustomTablemodel::docTypeToString(DocType type)
{
    switch (type) {
    case InstallGuide:
        return "安装指南";
    case UserManual:
        return "说明文档";
    case DesignDoc:
        return "设计文档";
    default:
        return "其他文档";
    }
}

DocType CustomTablemodel::stringToDocType(const QString &typeStr)
{
    if (typeStr == "安装指南")
        return InstallGuide;
    else if (typeStr == "说明文档")
        return UserManual;
    else if (typeStr == "设计文档")
        return DesignDoc;
    else
        return OtherDoc;
}

QIcon CustomTablemodel::getFileIcon(const QString &fileType) const
{
    QFileIconProvider provider;//判断文件类型返回对应的图标
    return provider.icon(QFileIconProvider::File);
}

QColor CustomTablemodel::getStatusColor(int status) const
{
    //根据行状态设置不同的背景色
    switch (status) {
    case 1: // 正常
        return QColor(240, 255, 240);
    case 2: // 警告
        return QColor(255, 255, 240);
    case 3: // 错误
        return QColor(255, 240, 240);
    default:
        return QColor(255, 255, 255);
    }
}
